home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks96 / FlyPaper.sit / Fly Paper / FlyPaper Source / Extension Sources / FlyPaperPatch.cpp < prev    next >
C/C++ Source or Header  |  1996-06-22  |  5KB  |  219 lines

  1. #include <A4Stuff.h>
  2. #include "FlyPaperPatch.h"
  3. #include "FlyPaperINIT.h"
  4. #include "FlyPaperDragUtils.h"
  5.  
  6. typedef enum {
  7.     kIdleState,
  8.     kStartedPegged,
  9.     kDraggingState,
  10.     kPeggedState,
  11.     kDroppedState
  12. } MachineState;
  13.  
  14. typedef enum {
  15.     kLeftSide,
  16.     kRightSide
  17. } Side;
  18.  
  19. typedef enum {
  20.     kUnknown,
  21.     kAcceptable,
  22.     kUnacceptable
  23. } Acceptability;
  24.  
  25. #define                    kFlyAnimateDelay    2
  26.  
  27. MachineState            gMachineState = kIdleState;
  28. RgnHandle                gNarrowGrayRgn = NULL;
  29. Cursor                    gOldCursor;
  30.  
  31. short                    gWhichFly = 0;
  32. unsigned long            gFlyTime = 0;
  33. FlyPaperGestaltPtr        gFlyPaperINITData = NULL;
  34. Rect                    gGrayRgnRect;
  35. Acceptability            gAcceptability;
  36.  
  37. static
  38. Acceptability    CheckAcceptability (DragReference dragRef)
  39. {
  40.     if (gAcceptability == kUnknown)
  41.         gAcceptability = AcceptableDrag (dragRef) ? kAcceptable : kUnacceptable;
  42.     
  43.     return gAcceptability;
  44. }
  45.  
  46. static FlyPaperGestaltPtr GetINITData ()
  47. {
  48.     if (gFlyPaperINITData == NULL) {
  49.         Gestalt (kSignature, (long*) &gFlyPaperINITData);
  50.     }
  51.     return gFlyPaperINITData;
  52. }
  53.  
  54. static void RememberCursor ()
  55. {
  56.     BlockMoveData ((void*) 0x00000844, &gOldCursor, sizeof (Cursor));
  57. }
  58.  
  59. static void MySetCursor (Cursor* cursor)
  60. {
  61.     // Call SetCursor directly through jSetCursor, since someone's stupid patch does not allow
  62.     // SetCursor to operate properly.  :-(
  63.     // Wish I knew why I was passing in 16, but the ROM does it.  When in ROMe...
  64.     
  65.     typedef pascal void (*jSetCrsrProc) (Point, short, void*, void*);    
  66.     (*((jSetCrsrProc*) 0x00000818)) (cursor -> hotSpot, 16, &cursor -> data, &cursor -> mask);
  67. }
  68.  
  69. static void AnimateFly ()
  70. {
  71.     unsigned long            now = TickCount ();
  72.     
  73.     if (now >= gFlyTime) {
  74.         gWhichFly = gWhichFly ^ 1;            // toggle between 0 and 1
  75.         MySetCursor (&GetINITData () -> flyCursors [gWhichFly]);        
  76.         gFlyTime = now + kFlyAnimateDelay;
  77.     }
  78. }
  79.  
  80. static void PrepareFlyCursors (Side whichSide)
  81. {
  82.     // Move the hotspot to ensure a visible fly
  83.     
  84.     FlyPaperGestaltPtr        flyPaperINITData = GetINITData ();
  85.     
  86.     if (whichSide == kLeftSide) {
  87.         flyPaperINITData -> flyCursors [0].hotSpot.h = 0;
  88.         flyPaperINITData -> flyCursors [1].hotSpot.h = 0;
  89.     } else {
  90.         flyPaperINITData -> flyCursors [0].hotSpot.h = 15;
  91.         flyPaperINITData -> flyCursors [1].hotSpot.h = 15;    
  92.     }
  93. }
  94.  
  95. static Boolean    IsMousePegged (Point mouse, Side* whichSide)
  96. {
  97.     Boolean            pegged;
  98.     
  99.     if (gNarrowGrayRgn == NULL) {
  100.         THz        oldZone = GetZone ();
  101.         SetZone (SystemZone ());
  102.         gNarrowGrayRgn = NewRgn ();
  103.         CopyRgn (GetGrayRgn (), gNarrowGrayRgn);
  104.         SetZone (oldZone);
  105.         InsetRgn (gNarrowGrayRgn, 2, 0);
  106.         gGrayRgnRect = (**GetGrayRgn()).rgnBBox;
  107.     }
  108.     
  109.     /* return true if mouse is pegged to edges */
  110.     pegged = PtInRgn (mouse, GetGrayRgn ()) && !PtInRgn (mouse, gNarrowGrayRgn);
  111.     if (pegged) {
  112.         if (mouse.h - gGrayRgnRect.left > gGrayRgnRect.right - mouse.h)
  113.             *whichSide = kRightSide;
  114.         else
  115.             *whichSide = kLeftSide;
  116.         return true;
  117.     } else
  118.         return false;
  119. }
  120.  
  121. static
  122. pascal OSErr myInputProc (Point* mouse, short *modifiers, void *dragInputRefCon,
  123.         DragReference theDragRef)
  124. {
  125.     EnterCodeResource ();
  126.     OSErr        error = noErr;
  127.     Side        whichSide;
  128.         
  129.     if (gMachineState == kStartedPegged) {
  130.         if ((*modifiers & btnState) == 0 && !IsMousePegged (*mouse, &whichSide)) {
  131.             gMachineState = kDraggingState;
  132.         }
  133.     } else if (gMachineState == kDraggingState) {
  134.         if ((*modifiers & btnState) == 0 && IsMousePegged (*mouse, &whichSide) &&
  135.                 (CheckAcceptability (theDragRef) == kAcceptable)) {
  136.             gMachineState = kPeggedState;
  137.             PrepareFlyCursors (whichSide);
  138.             RememberCursor ();
  139.             AnimateFly ();
  140.         }
  141.     } else if (gMachineState == kPeggedState) {
  142.         if ((*modifiers & btnState) == 0) {
  143.             if (IsMousePegged (*mouse, &whichSide)) {
  144.                 AnimateFly ();
  145.             } else {
  146.                 gMachineState = kDraggingState;
  147.                 MySetCursor (&gOldCursor);
  148.             }
  149.         } else {
  150.             if (IsMousePegged (*mouse, &whichSide)) {
  151.                 gMachineState = kDroppedState;
  152.                 MySetCursor (&gOldCursor);
  153.             
  154.                 WindowPtr        w = GetINITData () -> magicWindow;
  155.                 if (w) {
  156.                     MoveWindow (w, mouse -> h - 1, mouse -> v - 1, false);
  157.                 }
  158.             }
  159.         }
  160.     }
  161.     
  162.     ExitCodeResource ();
  163.     return error;
  164. }
  165.  
  166. static
  167. void myNewDrag (NewDragParms* parms)
  168. {
  169.     gMachineState = kIdleState;
  170.     
  171.     // Force recalculation of gray rgn
  172.     
  173.     if (gNarrowGrayRgn) {
  174.         DisposeRgn (gNarrowGrayRgn);
  175.         gNarrowGrayRgn = NULL;
  176.     }
  177. }
  178.  
  179. static
  180. void mySetDragInputProc (SetDragInputProcParms* parms)
  181. {
  182. }
  183.  
  184. static
  185. void myTrackDrag (TrackDragParms* parms)
  186. {
  187.     OSErr            error;
  188.         
  189.     error = SetDragInputProc (parms -> theDragRef, myInputProc, 0);
  190.     if (error) {
  191.         gMachineState = kIdleState;
  192.     } else {
  193.     
  194.         FlyPaperGestaltPtr        data = GetINITData ();
  195.         if (data && data -> magicWindow) {
  196.             Side        whichSide;
  197.             if (IsMousePegged (parms -> theEvent -> where, &whichSide))
  198.                 gMachineState = kStartedPegged;
  199.             else
  200.                 gMachineState = kDraggingState;
  201.             gAcceptability = kUnknown;
  202.         } else
  203.             gMachineState = kIdleState;
  204.     }
  205. }
  206.  
  207. void main (short selector, void* stackFrame)
  208. {
  209.     EnterCodeResource ();
  210.             
  211.     switch (selector) {
  212.         case kNewDragSelector : myNewDrag ((NewDragParms*) stackFrame); break;
  213.         case kSetDragInputProcSelector : mySetDragInputProc ((SetDragInputProcParms*) stackFrame); break;
  214.         case kTrackDragSelector : myTrackDrag ((TrackDragParms*) stackFrame); break;
  215.     }
  216.         
  217.     ExitCodeResource ();    
  218. }
  219.